package bb.lanxing.activity.mine;

import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.umeng.analytics.MobclickAgent;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import bb.lanxing.App;
import bb.lanxing.R;
import bb.lanxing.activity.base.BaseActivity;
import bb.lanxing.adapter.SportsRankDetailAdapter;
import bb.lanxing.common.config.UmengEventConst;
import bb.lanxing.model.database.User;
import bb.lanxing.model.database.Workout;
import bb.lanxing.model.json.RankUserDetail;
import bb.lanxing.network.MyHttpClient;
import bb.lanxing.network.NetSubscribe;
import bb.lanxing.util.MedalUtil;
import bb.lanxing.util.UserAvatarUtil;
import bb.lanxing.view.BikeHeader;
import bb.lanxing.view.UserAvatarView;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

import java.util.ArrayList;
import java.util.List;

public class SportsRankDetailActivity extends BaseActivity {
    private static final String TAG = "SportsRankDetailActivity";
    public static final int TIME_TYPE_ANNUAL = 2;
    public static final int TIME_TYPE_MONTHLY = 3;
    public static final int AREA_TYPE_CITY = 0;
    public static final int AREA_TYPE_NATIONAL = 1;
    public static final int MAX_ITEM_PER_PAGE = 20;
    Handler handler = new Handler();
    private SportsRankDetailAdapter adapter;
    private String title;
    private int sportType;
    private int timeType;
    private int regionId;
    private int regionType;
    private ListView rankUserListView;
    private View headerView;
    private LinearLayout mainLayout;
    private RankUserDetail currentUserRankInfo;
    private PtrFrameLayout ptrFrameLayout;
    private User currentUser;

    private List<RankUserDetail> userList = new ArrayList<>();
    private int pageIndex = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sports_rank_detail_activity);
        setupActionBar(true);
        retrieveIntentData();
        setupViews();
        initializeView();
        triggerRefresh();
    }

    private void scrollToTop() {
        rankUserListView.smoothScrollToPositionFromTop(0, 0, 300);
    }

    private void retrieveIntentData() {
        if (!App.getContext().isUserSignin()) {
            App.getContext().userSignin();
            return;
        }
        currentUser = App.getContext().getSigninUser();
        Intent intent = getIntent();
        sportType = intent.getIntExtra("sport_type", Workout.TYPE_CYCLING);
        title = intent.getStringExtra("title");
        regionId = intent.getIntExtra("area_id", 0);
        timeType = intent.getIntExtra("time_type", TIME_TYPE_ANNUAL);
        regionType = intent.getIntExtra("area_type", AREA_TYPE_NATIONAL);
    }

    private void initializeView() {
        if (currentUser != null) {
            headerView = LayoutInflater.from(this).inflate(R.layout.sports_rank_detail_header, null);
            refreshCurrentUserDetails();
            rankUserListView.addHeaderView(this.headerView);
        }

        BikeHeader bikeHeader = new BikeHeader(this);
        ptrFrameLayout.setHeaderView(bikeHeader);
        ptrFrameLayout.addPtrUIHandler(bikeHeader);
        ptrFrameLayout.setPtrHandler(new PtrDefaultHandler() {
            @Override
            public void onRefreshBegin(PtrFrameLayout ptrFrameLayout) {
                fetchRankData(true, timeType, regionId, regionType, sportType);
            }
        });

        mainLayout.setVisibility(View.VISIBLE);
        adapter = new SportsRankDetailAdapter(userList, this);
        adapter.setOnLoadEndListener(() -> fetchRankData(false, timeType, regionId, regionType, sportType));
        rankUserListView.setAdapter(adapter);
        rankUserListView.setOnItemClickListener((parent, view, position, id) -> {
            RankUserDetail rankUserDetail = position != 0 ? userList.get(position - 1) : currentUserRankInfo;
            if (rankUserDetail != null) {
                UserAvatarUtil.getInstance().goToUserInfo(SportsRankDetailActivity.this, rankUserDetail.getUserId(), rankUserDetail);
                MobclickAgent.onEventValue(SportsRankDetailActivity.this, UmengEventConst.OTHER_WORKOUT_LIST_RANK, null, 1);
            }
        });
    }

    private void setupViews() {
        rankUserListView = findViewById(R.id.user_rank_list_view);
        ptrFrameLayout = findViewById(R.id.ptr_frame_layout);
        mainLayout = findViewById(R.id.sport_rank_detail_main_layout);
        findViewById(R.id.toolbar).setOnClickListener(view -> scrollToTop());
        TextView actionBarTitle = findViewById(R.id.toolbar_title);
        actionBarTitle.setText(title);
    }

    private void triggerRefresh() {
        ptrFrameLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                ptrFrameLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                ptrFrameLayout.autoRefresh();
            }
        });
    }

    private void setTextViewText(View parent, int textViewId, String text) {
        ((TextView) parent.findViewById(textViewId)).setText(text);
    }

    private void configureUserAvatarView(UserAvatarView userAvatarView) {
        userAvatarView.setAvatarMode(UserAvatarView.AVATAR_SIZE_48);
        userAvatarView.setAvatarForUrl(currentUser.getPhotoUrl());
        userAvatarView.setUserLevelText(currentUser.getLevel());
    }

    private boolean isEmpty(String str) {
        return str == null || str.isEmpty();
    }

    private void refreshCurrentUserDetails() {
        if (this.currentUser == null || this.currentUserRankInfo == null) {
            return;
        }
        handler.post(() -> {
            if (Build.VERSION.SDK_INT < 17 || !SportsRankDetailActivity.this.isDestroyed()) {
                headerView.findViewById(R.id.sport_rank_detail_header).setVisibility(View.VISIBLE);
                UserAvatarView userAvatarView = headerView.findViewById(R.id.photoView);
                LinearLayout medalContainerLayout = headerView.findViewById(R.id.medal_container_layout);

                setTextViewText(headerView, R.id.nameView, currentUser.getName());
                setTextViewText(headerView, R.id.rankingView, String.valueOf(currentUserRankInfo.getRank()));
                setTextViewText(headerView, R.id.hotView, String.valueOf(currentUserRankInfo.getHots()));
                setTextViewText(headerView, R.id.header_city_name, currentUserRankInfo.getCityName());

                configureUserAvatarView(userAvatarView);

                boolean showAvatarFrame = !isEmpty(currentUserRankInfo.getProName());
                userAvatarView.setProTitle(showAvatarFrame ? currentUserRankInfo.getProName() : null);
                userAvatarView.isShowAvatarFrame(showAvatarFrame);

                MedalUtil.showAvatarMedal(
                        currentUserRankInfo.getMedalSmall(),
                        medalContainerLayout,
                        currentUserRankInfo.getPlateNum(),
                        showAvatarFrame,
                        SportsRankDetailActivity.this,
                        currentUserRankInfo.getUserAvatarMedals(),
                        currentUserRankInfo.getLicenseNumberSkin(),
                        currentUserRankInfo.getLicenseNumberColor()
                );
            }
        });
    }

    private void refreshView(List<RankUserDetail> rankUserDetails, int page) {
        if (rankUserDetails.isEmpty()) {
            return;
        }
        if (page == 0) {
            currentUserRankInfo = rankUserDetails.remove(0);
        }
        if (currentUserRankInfo.getUserId() > 0 && page == 0) {
            refreshCurrentUserDetails();
        }
        if (adapter != null && !rankUserDetails.isEmpty()) {
            if (page == 0) {
                userList.clear();
//                adapter.notifyDataSetChanged();
            }
            userList.addAll(rankUserDetails);
            adapter.notifyDataSetChanged();
        }
        adapter.setLoadMoreEnabled(rankUserDetails.size() >= MAX_ITEM_PER_PAGE);
    }

    private void completeRefresh() {
        if (adapter != null) {
            adapter.setLoadingMoreFinished();
        }
        handler.post(() -> {
            if (ptrFrameLayout != null) {
                ptrFrameLayout.refreshComplete();
            }
        });
    }

    private void fetchRankData(boolean isPullDown, int timeType, int regionId, int regionType, int sportType) {
//        Log.d(TAG, "fetchRankData begin isPullDown = " + isPullDown);
        if (isPullDown) {
            this.pageIndex = 0;
        }

        Observable.create(new NetSubscribe(MyHttpClient
                        .requestRankUserHot(timeType, regionId, regionType, sportType, MAX_ITEM_PER_PAGE,
                                pageIndex + 1/*page number start from 1 at server side*/)))
                .subscribeOn(Schedulers.io())
                /*.map(response -> parseRankUserDetails(response))*/
                .map(this::parseRankUserDetails)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<>() {
                    @Override
                    public void onCompleted() {
                        completeRefresh();
                    }

                    @Override
                    public void onError(Throwable e) {
                        completeRefresh();
                    }

                    @Override
                    public void onNext(List<RankUserDetail> rankUserDetails) {
                        completeRefresh();
                        refreshView(rankUserDetails, SportsRankDetailActivity.this.pageIndex);
                        if (rankUserDetails.size() >= MAX_ITEM_PER_PAGE) {
                            SportsRankDetailActivity.this.pageIndex += 1;
                        }
                    }
                });
    }

    private List<RankUserDetail> parseRankUserDetails(String response) {
        List<RankUserDetail> rankUserDetails = new ArrayList<>();
        try {
            JSONObject jsonObject = new JSONObject(response);
            RankUserDetail currentUserDetail = new RankUserDetail(jsonObject.getJSONObject("user"));
            JSONArray rankArray = jsonObject.getJSONArray("rank");
            for (int i = 0; i < rankArray.length(); i++) {
                rankUserDetails.add(new RankUserDetail(rankArray.getJSONObject(i)));
            }
            if (pageIndex == 0) {
                rankUserDetails.add(0, currentUserDetail);
            }
        } catch (JSONException e) {
            Log.e(TAG, "Error parsing rank user details", e);
        }
        return rankUserDetails;
    }
}
